#include "stringutils.h"

char *createBufferCopy(const char *buffer) {
    // printf("%s - 进入 拷贝 - %s\n", __FUNCTION__, buffer);
    if (buffer == NULL) return NULL;
    int len = strlen(buffer);

    // char *buf = (char*)malloc(len+1);
    // memset(buf, 0, len+1);
    char* buf = calloc(1, len+1);
    strcpy(buf, buffer);
    // printf("%s - 出去\n", __FUNCTION__);
    return buf;
}

// Line Has Value
bool LineHasValue(const char *buffer, const char *value) {
    // printf("%s - 进入\n", __FUNCTION__);
    const char *p = buffer;
    for (int i = 0; i < strlen(buffer); i++) {
        if (strlen(p)>=strlen(value) && strncmp(p+i, value,strlen(value)) == 0) {
            // printf("%s - 出去\n", __FUNCTION__);
            return true;
        }
    }
    // printf("%s - 出去\n", __FUNCTION__);
    return false;
}

bool LineStartWith(char *buffer, char *value) {
    // printf("%s - 进入\n", __FUNCTION__);
    char *p = buffer;
    if (strlen(p) >= strlen(value) && strncmp(p, value, strlen(value)) == 0) {
        // printf("%s - 出去\n", __FUNCTION__);
        return true;
    }
    // printf("%s - 出去\n", __FUNCTION__);
    return false;
}

bool LineEqual(const char *buffer, const char *value) {
    if (strlen(buffer) == strlen(value) && strncmp(buffer, value, strlen(value)) == 0) {
        // printf("%s - 出去\n", __FUNCTION__);
        return true;
    }
    return false;
}

bool LineIsEmpty(const char *buffer) {
    // printf("%s - 进入\n", __FUNCTION__);
    if (strlen(buffer) == 0) return true;

    // printf("%s - 出去\n", __FUNCTION__);
    return false;
}

char* LineTrim(char *buffer) {
    // printf("%s - 进入\n", __FUNCTION__);
    if (buffer == NULL) return NULL;
    char *buf = createBufferCopy(buffer);
    char *start_of_wold;
    char *p = buf;

    while (g_ascii_isspace(*p) && *p != '\0') p++;
    start_of_wold = p;
    p = buf + strlen(buf);
    while (g_ascii_isspace(*p) || *p == '\0') p--;
    if (p==start_of_wold) {
        // free(buf);
        // printf("%d = %d\n",p,start_of_wold);
        // return NULL;
    }
    *(p+1) = 0;
    char * value = createBufferCopy(start_of_wold);
    free(buf);
    // printf("%s - 出去\n", __FUNCTION__);
    return value;
}

bool LineTrim_buf(char *buffer, char *dest) {
    char *buf = LineTrim(buffer);
    
    if (buf == NULL) return false;
    
    strcpy(dest, buf);
    free(buf);
    
    return true;
}

bool LineTrimIsEmpty(char *buffer) {
    char *buf = LineTrim(buffer);
    
    if (buf == NULL) return true;

    bool isEmpty = LineIsEmpty(buf);
    free(buf);

    return isEmpty;
}

GSList* split(const char *buf, char value) {
    // printf("%s - 进入\n", __FUNCTION__);
    GSList *list = NULL;
    char *p = NULL;
    char *start_of_word = NULL;

    if (buf == NULL) return NULL;

    char *buffer = createBufferCopy(buf);

    p = buffer;
    start_of_word = p;

    for (; *p != 0; p++)
    {
        if (*p == value) {
            *p = 0;
            list = g_slist_append(list, createBufferCopy(start_of_word));
            start_of_word = p+1;
            continue;
        }
    }

    if (strlen(start_of_word) > 0) {
        list = g_slist_append(list, createBufferCopy(start_of_word));
    }

    free(buffer);
    
    // printf("%s - 出去\n", __FUNCTION__);
    return list;
}

GSList* split_cnt(const char *buf, char value, int cnt) {
    // printf("%s - 进入\n", __FUNCTION__);
    GSList *list = NULL;
    char *p = NULL;
    char *start_of_word = NULL;
    int split_cnt = cnt;

    if (buf == NULL) return NULL;

    char *buffer = createBufferCopy(buf);

    p = buffer;
    start_of_word = p;

    for (; *p != 0 && split_cnt != 0; p++)
    {
        if (*p == value) {
            *p = 0;
            list = g_slist_append(list, createBufferCopy(start_of_word));
            start_of_word = p+1;
            split_cnt--;
            continue;
        }
    }

    if (strlen(start_of_word) > 0) {
        list = g_slist_append(list, createBufferCopy(start_of_word));
    }

    free(buffer);
    
    // printf("%s - 出去\n", __FUNCTION__);
    return list;
}

GSList* splits(const char *buf, const char *value) {
    // printf("%s - 进入\n", __FUNCTION__);
    GSList *list = NULL;
    char *p;
    char *start_of_word;

    if (buf == NULL) return NULL;

    char *buffer = createBufferCopy(buf);

    p = buffer;
    start_of_word = p;

    for (; *p != '\0'; )
    {
        if (strlen(p) >= strlen(value) && strncmp(p, value, strlen(value)) == 0) {
            *(p) = 0;
            list = g_slist_append(list, createBufferCopy(start_of_word));
            start_of_word = p + strlen(value);
            p += strlen(value);
        } else {
            p++;
        }
    }

    if (strlen(start_of_word) > 0) {
        list = g_slist_append(list, createBufferCopy(start_of_word));
    }
    
    // printf("%s - 出去\n", __FUNCTION__);
    return list;
}

char * LineReplace(const char *buf, const char *old, const char *replace) {
    if (buf == NULL) return NULL;
    if (old == NULL) return NULL;
    if (replace == NULL) return NULL;

    if (!LineHasValue(buf, old)) return createBufferCopy(buf);
    
    GSList *list = splits(buf, old);
    
    int length = g_slist_length(list) * strlen(replace) + strlen(buf);
    
    char buffer[length];
    memset(buffer, 0, length);

    for (GSList *iter = list; iter; iter = iter->next) {
        strcat(buffer, iter->data);
        if (iter != g_slist_last(list)) strcat(buffer, replace);
    }
    
    GS_FREE_ALL_CLEAN(list);

    return createBufferCopy(buffer);
}

// void LineReplace_buf(char *buf, const char *old, const char *replace) {
//     char *value = LineReplace(buf, old, replace)
// }

bool splitToString(GSList *list, char *buffer) {
    GSList *iter = NULL;
    for (iter = list; iter; iter = iter->next) {
        strcat(buffer, iter->data);
    }
    return true;
}

bool splitToStringWithTrim(GSList *list, char *buffer) {
    GSList *iter = NULL;
    for (iter = list; iter; iter = iter->next) {
        LineTrim_buf(iter->data, iter->data);
        strcat(buffer, iter->data);
    }
    return true;
}

bool splitToStringWithSeparator(GSList *list, const char *sep, char *buffer) {
    GSList *iter = NULL;
    for (iter = list; iter; iter = iter->next) {
        strcat(buffer, iter->data);
        if (iter != g_slist_last(list)) {
            strcat(buffer, sep);
        }
    }
    return true;;
}

void printf_iterator(gpointer item, gpointer prefix) {
    printf("%s %s\n", (char*)prefix, (char*)item);
}

bool isNull(const char *str) {
    if (str == NULL) return true;
    return false;
}
